package com.java.framework.service.impl;

import java.io.Serializable;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.java.framework.jpa.repository.BaseRepository;
import com.java.framework.service.BaseService;

@Transactional(readOnly = true)
public class BaseServiceImpl<T, ID extends Serializable> implements BaseService<T,ID> {

    @Autowired
    protected BaseRepository<T,ID> repository ;

    @Override
    public T getOne(ID id) {
        return repository.getOne(id);
    }

    @Override
    public T findOne(ID id) {
        return repository.findOne(id);
    }

    @Override
    public <S extends T> S findOne(Example<S> example) {
        return repository.findOne(example);
    }

    @Override
    public T findOne(Specification<T> spec) {
        return repository.findOne(spec);
    }

    @Override
    public List<T> findAll() {
        return repository.findAll();
    }

    @Override
	public List<T> findAll(Specification<T> spec) {
		return repository.findAll(spec);
	}

	@Override
	public List<T> findAll(Specification<T> spec, Sort sort) {
		return repository.findAll(spec, sort);
	}

	@Override
    public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
        return repository.findAll(example, pageable);
    }

    @Override
    public Page<T> findAll(Specification<T> spec, Sort sort, int currentPage, int pageSize) {
        return this.findAll(spec,this.buildPageRequest(currentPage,pageSize,sort));
    }

    @Override
    public Page<T> findAll(Specification<T> spec, Pageable pageable) {
    	if(pageable != null)
    		return repository.findAll(spec, this.buildPageRequest(pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort()));
        return repository.findAll(spec,pageable);
    }

    @Override
    public boolean exists(ID id) {
        return repository.exists(id);
    }

    @Override
    public <S extends T> boolean exists(Example<S> example) {
        return repository.exists(example);
    }

    @Override
    @Transactional
    public <S extends T> S save(S entity) {
        return repository.save(entity);
    }

    @Override
    @Transactional
    public <S extends T> List<S> save(Iterable<S> entities) {
    	if(entities == null) return null ;
    	List<S> results = Lists.newArrayList() ;
    	for(S entity : entities) {
    		results.add(this.save(entity)) ;
    	}
        return results;
    }

    @Override
    @Transactional
    public void delete(ID id) {
        repository.delete(id);
    }

    @Override
    @Transactional
    public void delete(T entity) {
        repository.delete(entity);
    }

    @Override
    @Transactional
    public void deleteInBatch(Iterable<T> entities) {
        repository.deleteInBatch(entities);
    }

    @Override
    @Transactional
    public void deleteAllInBatch() {
        repository.deleteAllInBatch();
    }

    /**
     * 创建分页请求.
     */
    protected PageRequest buildPageRequest(int currentPage, int pageSize, Sort sort) {
        if(sort == null){ //TODO:如果没有排序条件，则默认id排序
            sort = new Sort(Sort.Direction.ASC, "id");
        }
        return new PageRequest(Math.max(currentPage, 0), pageSize, sort);
    }

}
